///////////////////
/// mkII - Core ///
///////////////////

#pragma once

namespace mk
{
namespace Core
{
namespace Math
{

MK_FORCEINLINE Vector1::MK_MATH_VECTOR1_CTOR
(
)
{
}

MK_FORCEINLINE Vector1::MK_MATH_VECTOR1_CTOR
(
    real32 const v
)
{
    *this = v;
}

MK_FORCEINLINE Vector1::MK_MATH_VECTOR1_CTOR
(
    Vector128r v
)
{
    r = v;
}

MK_FORCEINLINE Vector1::MK_MATH_VECTOR1_CTOR
(
    Vector128i v
)
{
    i = v;
}

MK_FORCEINLINE Vector1::operator real32( ) const
{
    real32 result;
    StoreVector1( &result, *this );
    return result;
}

MK_FORCEINLINE Vector1& Vector1::operator=
(
    real32 v
)
{
    return *this = LoadVector1( &v );
}

MK_FORCEINLINE Vector1& Vector1::operator=
(
    Vector128r v
)
{
    r = v;
    return *this;
}

MK_FORCEINLINE Vector1& Vector1::operator=
(
    Vector128i v
)
{
    i = v;
    return *this;
}

MK_FORCEINLINE bool operator==
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return IsEqual(a, b);
}

MK_FORCEINLINE bool operator!=
(
Vector1ConstValue a,
Vector1ConstValue b
)
{
    return !(a == b);
}

MK_FORCEINLINE bool operator<
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return IsLess(a, b);
}

MK_FORCEINLINE bool operator<=
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return IsLessEq(a, b);
}

MK_FORCEINLINE bool operator>
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return IsGreater(a, b);
}

MK_FORCEINLINE bool operator>=
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return IsGreaterEq(a, b);
}

MK_FORCEINLINE Vector1ConstValue operator+
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return Add(a, b);
}

MK_FORCEINLINE Vector1ConstValue operator-
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return Sub(a, b);
}

MK_FORCEINLINE Vector1ConstValue operator*
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return Mul(a, b);
}

MK_FORCEINLINE Vector1ConstValue operator/
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return Div(a, b);
}

MK_FORCEINLINE Vector1& operator+=
(
    Vector1&            a,
    Vector1ConstValue   b
)
{
    return a = Add(a, b);
}

MK_FORCEINLINE Vector1& operator-=
(
    Vector1&            a,
    Vector1ConstValue   b
)
{
    return a = Sub(a, b);
}

MK_FORCEINLINE Vector1& operator*=
(
    Vector1&            a,
    Vector1ConstValue   b
)
{
    return a = Mul(a, b);
}

MK_FORCEINLINE Vector1& operator/=
(
    Vector1&            a,
    Vector1ConstValue   b
)
{
    return a = Div(a, b);
}

MK_FORCEINLINE Vector1 operator+
(
    Vector1ConstValue v
)
{
    return v;
}

MK_FORCEINLINE Vector1 operator-
(
    Vector1ConstValue v
)
{
    return XOr( v, Vector1(Constants::uint_sign_mask) );
}

MK_FORCEINLINE Vector1ConstValue LengthSq
(
    Vector1ConstValue v
)
{
    return Mul( v, v );
}

MK_FORCEINLINE Vector1ConstValue SafeReciprocal
(
    Vector1ConstValue v,
    Vector1ConstValue r
)
{
    Vector1 grMask = IsGreaterMask( Abs(v), Vector1(Constants::real4_epsilon) );
    return Select( grMask, Reciprocal(v), r );
}

MK_FORCEINLINE Vector1ConstValue ReciprocalSqrt
(
    Vector1ConstValue v
)
{
    return Reciprocal(Sqrt(v));
}

MK_FORCEINLINE Vector1ConstValue SafeReciprocalSqrt
(
    Vector1ConstValue v,
    Vector1ConstValue r
)
{
    Vector1 vsqrt  = Sqrt(v);
    Vector1 grMask = IsGreaterMask( Abs(vsqrt), Vector1(Constants::real4_epsilon) );
    return Select( grMask, Reciprocal(vsqrt), r );
}

MK_FORCEINLINE Vector1ConstValue Abs
(
    Vector1ConstValue v
)
{
    return And( v, Vector1(Constants::uint_value_mask) );
}


MK_FORCEINLINE Vector1ConstValue Lerp
(
    Vector1ConstValue a,
    Vector1ConstValue b,
    Vector1ConstValue t
)
{
    return MAdd((b - a), t, a);
}

MK_FORCEINLINE Vector1ConstValue Clamp
(
    Vector1ConstValue v,
    Vector1ConstValue min,
    Vector1ConstValue max
)
{
    return Max( Min( v, max ), min );
}

MK_FORCEINLINE Vector1ConstValue IsGreaterMask
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return IsLessMask( b, a );
}

MK_FORCEINLINE Vector1ConstValue IsGreaterEqMask
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    return IsLessEqMask( b, a );
}

MK_FORCEINLINE bool IsEqual
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    Vector1 mask = IsEqualMask(a, b);
    return IsTrue(mask);
}

MK_FORCEINLINE bool IsLess
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    Vector1 mask = IsLessMask(a, b);
    return IsTrue(mask);
}

MK_FORCEINLINE bool IsLessEq
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    Vector1 mask = IsLessEqMask(a, b);
    return IsTrue(mask);
}

MK_FORCEINLINE bool IsGreater
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    Vector1 mask = IsGreaterMask(a, b);
    return IsTrue(mask);
}

MK_FORCEINLINE bool IsGreaterEq
(
    Vector1ConstValue a,
    Vector1ConstValue b
)
{
    Vector1 mask = IsGreaterEqMask(a, b);
    return IsTrue(mask);
}

MK_FORCEINLINE bool IsFinite
(
    Vector1ConstValue v
)
{
    return IsLessEq( Abs(v), Vector1( MK_REAL32_MAX ) );
}

} // namespace Math
} // namespace Core
} // namespace mk

#include "../../../Core/Math/Windows/mkVector1SSE.inl"

